//
// Created by haoy on 2017/6/20.
//

#ifndef RTC_XSWITCH2_RTP_PACKET_HPP
#define RTC_XSWITCH2_RTP_PACKET_HPP

#include <cstdint>
#include <map>

#include "codecs.hpp"
#include "rtp/rtp_fec.hpp"
#include "rtp/rtp_header.hpp"
#include "rtp/rtp_map.hpp"
#include "rtp/rtp_red.hpp"
#include "rtp/rtp_rtx.hpp"
#include "rtp_exten.hpp"

/// RtpPacket represent an RTP packet, which can be:
/// - a trivial RTP packet contains media data
/// - an fec packet
/// - a red packet
/// - an rtx packet
/// To get access of fec fields, you need to up cast the RtpPacket* to RtpFec*
/// Such design RtpPacket is-a RtpFec, is to make reuse easier,
/// e.g. an fec packet can be recycled, then allocated as a red packet
///
class RtpPacket {
public:
    static constexpr int MAX_BUF = 1600;
public:
    RtpHeader header;
    rtc_codec_id_t codec_id = rtc_codec_id_unknown; // codec value defined in xrtc_endpoint.cpp
    uint8_t buffer[MAX_BUF];
    int buffer_size = 0;
    uint8_t* csrc = 0;
    int csrc_len = 0;
    uint8_t* ext = 0;
    int ext_len = 0;
    uint8_t* payload = 0;
    int payload_size = 0;
    int padding_size = 0;
    bool is_recovered = false;
public:
    RtpPacket();
    RtpPacket(const RtpPacket&) = delete;
    RtpPacket& operator=(const RtpPacket&) = delete;

    int read(const uint8_t *data, const int size, rtc_codecs_t* codecs);
    int write(uint8_t *data, const int size, rtc_codecs_t* codecs) const;
    int size() const;
    void reset() {
        is_recovered = false;
    }

    RtpFec fec;
    RtpRed red;
    RtpRtx rtx;
    RtpExtensions extens;
};

#endif //RTC_XSWITCH2_RTP_PACKET_HPP
